import { AxiosRequestConfig } from '../types';
import { isObject, deepMerge } from '../helpers/utils';

const stratStrategy = Object.create(null);
function defaultStrat(val1: any, val2: any): any {
  return val2 === undefined ? val1 : val2;
}
function fromVal2Strat(_val1: any, val2: any): any {
  if (val2 !== undefined) {
    return val2;
  }
}

function deepMergeStrat(val1: any, val2: any): any {
  if (isObject(val2)) {
    const result = deepMerge(val1, val2);
    return result;
  } else if (val2 !== undefined) {
    return val2;
  } else if (isObject(val1)) {
    return deepMerge(val1);
  } else if (val1 !== undefined) {
    return val1;
  }
}

const val2StratKey = ['url', 'params', 'data'];
const deepMergeStratKey = ['headers', 'auth'];

val2StratKey.forEach(str => {
  stratStrategy[str] = fromVal2Strat;
});

deepMergeStratKey.forEach(str => {
  stratStrategy[str] = deepMergeStrat;
});

export default function mergeConfig(
  config1: AxiosRequestConfig,
  config2?: AxiosRequestConfig
): AxiosRequestConfig {
  if (!config2) {
    config2 = {};
  }
  const config = Object.create(null);
  for (let key in config1) {
    mergeField(key);
  }
  for (let key in config2) {
    mergeField(key);
  }
  function mergeField(key: string) {
    const strat = stratStrategy[key] || defaultStrat;
    config[key] = strat(config1[key], config2![key]);
  }
  return config;
}
